<template>
  <div v-loading="loading" class="table-web" :style="{ height: height }">
    <el-table
      ref="table"
      :data="data"
      stripe
      :table-layout="tableLayout"
      :border="border"
      :span-method="objectSpanMethod"
      :style="{ width: '100%', position: isFixed }"
      :height="tableHeight"
      :max-height="maxHeight"
      :highlight-current-row="true"
      :row-class-name="tableRowClassName"
      :header-cell-style="{
        background: bgColor,
        color: color,
        fontSize: '14px'
      }"
      :empty-text="emptyText"
      :show-summary="showSummary"
      :summary-method="summaryMethods"
      @row-click="rowClick"
      @selection-change="selectionChange"
      @select="select"
      @selectAll="selectAll"
      @sort-change="sortChange"
    >
      <!-- :summary-method="summaryMethods" -->
      <!-- <div slot="empty" class="empty">
        <img width="22" src="@/assets/common/empty.png" />
        <el-empty :description="emptyText" />
      </div> -->
      <template #empty>
        <div class="empty">
          <img width="60" src="../../assets/img/common/empty.png" />
          <span>暂无数据</span>
        </div>
      </template>
      <!-- 多选框 -->
      <el-table-column
        v-if="selection"
        type="selection"
        width="40"
        :selectable="checkboxSelect"
        fixed="left"
      />
      <!-- 序号 -->
      <el-table-column
        v-if="indexT"
        type="index"
        width="60px"
        label="序号"
        fixed="left"
        :align="columnClass"
        :header-align="headColumnClass"
      />

      <!-- 业务逻辑代码 -->
      <el-table-column
        v-for="(item, index) in column"
        :key="index"
        :prop="item.prop"
        :sortable="item.sortable"
        :label="item.label"
        :width="columnWidth(item, column.length)"
        :header-align="
          item.type === 'option'
            ? 'left'
            : item.headColumnClass
            ? item.headColumnClass
            : headColumnClass
        "
        :align="
          item.type === 'option'
            ? 'left'
            : item.columnClass
            ? item.columnClass
            : columnClass
        "
        :class-name="'tui-' + columnClass"
        :show-overflow-tooltip="
          item.type === 'option' || item.type === 'custom' ? false : true
        "
        :fixed="item.fixed"
      >
        <template v-if="item.header" #header>
          <slot name="tableHeader" />
        </template>
        <!-- 非嵌套表头 -->
        <template v-if="!item.children" v-slot="scope">
          <!-- formatTag: 1.是否类型（1.success 2.danger） 2.文本类型() -->
          <div v-if="item.type === 'tag'">
            <!-- boolean format -->
            <el-tag
              v-if="item.formatCode == 'boolean'"
              :type="scope.row[item.prop] == 1 ? 'default' : 'danger'"
            >
              {{ scope.row[item.prop] == 1 ? '是' : '否' }}
            </el-tag>

            <!-- 需要用后端code format-->
            <el-tag
              v-else
              :type="formatTagType(item.prop, scope.row[item.prop])"
            >
              {{ formatCode(item.formatCode, scope.row[item.prop]) }}
            </el-tag>
          </div>
          <!-- 开关 -->
          <slot
            v-else-if="item.type === 'switch'"
            name="switch"
            :row="scope.row"
          />
          <!-- 自定义内容 -->
          <slot
            v-else-if="item.type === 'custom'"
            name="custom"
            :row="scope.row"
          />
          <!-- 自定义内容 -->
          <slot
            v-else-if="item.type === 'custom-mul'"
            :name="'custom-' + item.prop"
            :row="scope.row"
          />
          <!-- 数字千分位 -->
          <span
            v-else-if="item.type === 'formatNumber'"
            v-money="scope.row[item.prop]"
          />
          <!-- 数字千分位 -->
          <span
              v-else-if="item.type === 'number'"
              v-money="scope.row[item.prop]"
            />
          <!-- 时间格式 -->
          <span v-else-if="item.type === 'time'">
            {{ formatTime(scope.row[item.prop], item.timeType) }}
          </span>
          <!-- 普通formart 前端固定的key-value -->
          <span v-else-if="item.type === 'format'">
            {{ formatCode(item.formatCode, scope.row[item.prop]) }}
          </span>
          <!-- 对象 -->
          <slot v-else-if="item.type === 'obj'" name="obj">
            {{ scope.row[item.prop]?.[item.name] }}
          </slot>
          <!-- 两层对象 -->
          <slot v-else-if="item.type === 'obj2'" name="obj">
            {{ scope.row[item.prop][item.prop1][item.name] }}
          </slot>
          <slot v-else-if="item.type === 'formatObj'" name="obj">
            {{
              formatDictCode(item.formatCode, scope.row[item.prop][item.prop1])
            }}
          </slot>
          <span
            v-else-if="item.type === 'formatDict'"
            :class="calFontColor(item.color, scope.row[item.prop])"
          >
            {{ formatDictCode(item.formatCode, scope.row[item.prop]) }}
            <!-- <span v-html="formatDictCode( item.formatCode, scope.row[item.prop])" /> -->
          </span>
          <!-- slot -->
          <slot
            v-else-if="item.slot"
            :name="item.slot"
            :row="scope.row"
            :index="scope.$index"
            :prop="item.prop"
          />
          <!-- 操作按钮通过插槽控制 -->
          <slot
            v-else-if="item.type === 'option'"
            name="option"
            :row="scope.row"
          />

          <!-- 正常数据展示 -->
          <span v-else>
            {{
              (scope.row && scope.row[item.prop]) ||
              formatDefault(scope.row[item.prop])
            }}
          </span>
        </template>
        <!-- 嵌套表头 -->
        <template v-slot="scope" v-else="item.children">
          <el-table-column
            v-for="(item1, index1) in item.children"
            :key="index1"
            :prop="item1.prop"
            :label="item1.label"
            :width="columnWidth(item1, item.children.length)"
            :align="columnClass"
            :class-name="'tui-' + columnClass"
            :show-overflow-tooltip="item1.showToolTip"
            :fixed="item1.fixed"
            :header-align="
            item1.type === 'option'
              ? 'left'
              : item1.headColumnClass
              ? item1.headColumnClass
              : headColumnClass
          "
          >
            <template v-if="!item1.children" v-slot="scope">
              <div v-if="item1.type === 'tag'">
                <!-- boolean format -->
                <el-tag
                  v-if="item.formatCode == 'boolean'"
                  :type="scope.row[item.prop] == 1 ? 'default' : 'danger'"
                >
                  {{ scope.row[item.prop] == 1 ? '是' : '否' }}
                </el-tag>

                <!-- 需要用后端code format-->
                <el-tag
                  v-else
                  :type="formatTagType(item.prop, scope.row[item.prop])"
                >
                  {{ formatCode(item.formatCode, scope.row[item.prop]) }}
                </el-tag>
              </div>
              <!-- 开关 -->
              <slot
                v-else-if="item1.type === 'switch'"
                name="switch"
                :row="scope.row"
              />
              <!-- 自定义内容 -->
              <slot
                v-else-if="item1.type === 'custom'"
                name="custom"
                :row="scope.row"
              />
              <!-- 数字千分位 -->
              <span
                v-else-if="item1.type === 'number'"
                v-money="scope.row[item1.prop]"
              />
              <!-- 时间格式 -->
              <span v-else-if="item1.type === 'time'">
                {{ formatTime(scope.row[item.prop], item.timeType) }}
              </span>
              <!-- 普通formart 前端固定的key-value -->
              <span v-else-if="item1.type === 'format'">
                {{ formatCode(item.formatCode, scope.row[item.prop]) }}
              </span>
              <!-- 对象 -->
              <slot v-else-if="item1.type === 'obj'" name="obj">
                {{ scope.row[item.prop][item.name] }}
              </slot>
              <!-- 两层对象 -->
              <slot v-else-if="item1.type === 'obj2'" name="obj">
                {{ scope.row[item.prop][item.prop1][item.name] }}
              </slot>
              <slot v-else-if="item1.type === 'formatObj'" name="obj">
                {{
                  formatDictCode(
                    item.formatCode,
                    scope.row[item.prop][item.prop1]
                  )
                }}
              </slot>
              <span
                v-else-if="item1.type === 'formatDict'"
                :class="calFontColor(item.color, scope.row[item1.prop])"
              >
                {{ formatDictCode(item1.formatCode, scope.row[item1.prop]) }}
                <!-- <span v-html="formatDictCode( item.formatCode, scope.row[item.prop])" /> -->
              </span>
              <!-- slot -->
              <slot
                v-else-if="item1.slot"
                :name="item1.slot"
                :row="scope.row"
                :index="scope.$index"
                :prop="item1.prop"
              />
              <!-- 操作按钮通过插槽控制 -->
              <slot
                v-else-if="item1.type === 'option'"
                name="option"
                :row="scope.row"
              />

              <!-- 正常数据展示 -->
              <span v-else>
                {{
                  (scope.row && scope.row[item1.prop]) ||
                  formatDefault(scope.row[item1.prop])
                }}
              </span>
            </template>
            <template v-slot="scope" v-else="item1.children">
          <el-table-column
            v-for="(item2, index2) in item1.children"
            :key="index2"
            :prop="item2.prop"
            :label="item2.label"
            :width="columnWidth(item2, item1.children.length)"
            :align="columnClass"
            :class-name="'tui-' + columnClass"
            :show-overflow-tooltip="item2.showToolTip"
            :fixed="item2.fixed"
          >
            <template v-slot="scope">
              <div v-if="item2.type === 'tag'">
                <!-- boolean format -->
                <el-tag
                  v-if="item1.formatCode == 'boolean'"
                  :type="scope.row[item1.prop] == 1 ? 'default' : 'danger'"
                >
                  {{ scope.row[item1.prop] == 1 ? '是' : '否' }}
                </el-tag>

                <!-- 需要用后端code format-->
                <el-tag
                  v-else
                  :type="formatTagType(item1.prop, scope.row[item1.prop])"
                >
                  {{ formatCode(item1.formatCode, scope.row[item1.prop]) }}
                </el-tag>
              </div>
              <!-- 开关 -->
              <slot
                v-else-if="item2.type === 'switch'"
                name="switch"
                :row="scope.row"
              />
              <!-- 自定义内容 -->
              <slot
                v-else-if="item2.type === 'custom'"
                name="custom"
                :row="scope.row"
              />
              <!-- 数字千分位 -->
              <span
                v-else-if="item2.type === 'number'"
                v-money="scope.row[item2.prop]"
              />
              <!-- 时间格式 -->
              <span v-else-if="item2.type === 'time'">
                {{ formatTime(scope.row[item1.prop], item1.timeType) }}
              </span>
              <!-- 普通formart 前端固定的key-value -->
              <span v-else-if="item2.type === 'format'">
                {{ formatCode(item1.formatCode, scope.row[item1.prop]) }}
              </span>
              <!-- 对象 -->
              <slot v-else-if="item2.type === 'obj'" name="obj">
                {{ scope.row[item1.prop][item1.name] }}
              </slot>
              <!-- 两层对象 -->
              <slot v-else-if="item2.type === 'obj2'" name="obj">
                {{ scope.row[item1.prop][item1.prop1][item1.name] }}
              </slot>
              <slot v-else-if="item2.type === 'formatObj'" name="obj">
                {{
                  formatDictCode(
                    item1.formatCode,
                    scope.row[item1.prop][item1.prop1]
                  )
                }}
              </slot>
              <span
                v-else-if="item2.type === 'formatDict'"
                :class="calFontColor(item1.color, scope.row[item2.prop])"
              >
                {{ formatDictCode(item2.formatCode, scope.row[item2.prop]) }}
                <!-- <span v-html="formatDictCode( item.formatCode, scope.row[item.prop])" /> -->
              </span>
              <!-- slot -->
              <slot
                v-else-if="item2.slot"
                :name="item2.slot"
                :row="scope.row"
                :index="scope.$index"
                :prop="item2.prop"
              />
              <!-- 操作按钮通过插槽控制 -->
              <slot
                v-else-if="item2.type === 'option'"
                name="option"
                :row="scope.row"
              />

              <!-- 正常数据展示 -->
              <span v-else>
                {{
                  (scope.row && scope.row[item2.prop]) ||
                  formatDefault(scope.row[item2.prop])
                }}
              </span>
            </template>
          </el-table-column>
        </template>
          </el-table-column>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script setup>
import dayjs from 'dayjs'
import { useScrollRecover } from '@/hooks/useTableScroll'
import { dictStore } from '@/pinia/modules/dict'
import { number } from 'echarts'
const dictStoreData = dictStore()
const table = ref(null)
useScrollRecover(table)

const auditStatusTag = {
  1: 'default',
  2: 'warning',
  3: 'danger',
  4: 'success',
  5: 'success',
  6: 'success'
}
let isFixed = ref('absolute')

const props = defineProps({
  isMergeSameOrgRow: {
    type: Boolean,
    default: false
  },
  isMergeSameOrgCol2: {
    type: Boolean,
    default: false
  },
  border: {
    type: Boolean,
    default() {
      return false
    }
  },
  isSummaryLastIndex: {
    type: Boolean,
    default() {
      return false
    }
  },
  emptyText: {
    type: String,
    default: '暂无数据'
  },
  showSummary: {
    type: Boolean,
    default() {
      return false
    }
  },
  tableSummaryUnits: {
    type: Array,
    default() {
      return []
    }
  },
  loading: {
    type: Boolean,
    default: () => {
      return false
    }
  },
  /* 选中行坐标，默认不选中 */
  getIndex: {
    type: Number,
    default: () => {
      return -1
    }
  },
  /* 多选框展示 */
  selection: {
    type: Boolean,
    default: () => {
      return false
    }
  },
  /* 列名 */
  columnClass: {
    type: String,
    default: 'left'
  },
  // 头部列名
  headColumnClass: {
    type: String,
    default: 'left'
  },
  /* head背景色 */
  bgColor: {
    type: String,
    default: () => {
      return '#F4F9FF'
    }
  },
  /* head字体颜色 */
  color: {
    type: String,
    default: () => {
      return '#087CD6'
    }
  },
  /* content表格高度 */
  height: {
    type: String,
    default: () => {
      return 'calc(100%)'
      // return 'calc(100% - 30px)'
    }
  },
  // 最大高度
  maxHeight: {
    type: [String, Number]
  },
  /* 序号列表是否展示，默认不展示 */
  indexT: {
    type: Boolean,
    default: () => {
      return false
    }
  },
  /* 列表展示结果 */
  data: {
    type: Array,
    default: () => {
      return []
    }
  },
  /* head内容 */
  column: {
    type: Array,
    default: () => {
      return [
        { label: '测试1', prop: 'name' },
        { label: '测试2', prop: 'size' },
        { label: '测试3', prop: 'size' },
        { label: '测试4', prop: 'size' }
      ]
    }
  },
  // 表头必填表示 传requiredName字符串
  headerRequired: {
    type: String,
    default: ''
  },
  // 默认家庭床位填报统计总计
  summary_type: {
    type: String,
    default: () => {
      return 'JTCWTBTJ'
    }
  },
  tableLayout: {
    type: String,
    default: () => {
      return 'fixed'
    }
  },
  selectable: {
    type: String
  },
  isAutoWidth: {
    type: [Boolean, Number, String],
    default: true
  }
})

const formatDefault = val => {
  return val === 0 || (val && val.length) ? val : '--'
}

defineExpose({
  table: table
})

const checkboxSelect = (row, rowIndex) => {
  if (props.selectable == 'PLGS') {
    if (row.publicStatus == 0) {
      return true // 不禁用
    } else {
      return false // 禁用
    }
  } else {
    return true
  }
}

const tableHeight = computed(() => {
  if (props.height === 'auto') {
    isFixed.value = 'static'
    return 'auto'
  } else {
    return '100%'
  }
})

const columnWidth = (item, length) => {
  if(item.type == 'option' || item.isFixedWidth) {
    return item.width
  }
  if ((item.prop == 'idCard' || item.prop == 'idNumber') && length > 6) {
    return 200
  }
  if (item.prop == 'projectName' && length > 2) {
    return 350
  }
  return props.isAutoWidth
    ? windowWidth.value > 1440
      ? ''
      : item.width
    : item.width
}

// watch([data],(newValue,oldValue)=>{
// 	console.log(newValue,oldValue)
// })

const calFontColor = (color, val) => {
  if (color && val == 0) {
    return 'error'
  }
  return false
}
const formatTime = (val, type) => {
  return val ? dayjs(val).format(type) : ' - '
}

// 前端写死的map key value
const formatCode = (code, val) => {
  return FRONT_CODE[code][val]
}
const formatDictCode = (code, val) => {
  // eslint-disable-next-line eqeqeq
  const target = dictStoreData.dict?.find(item => item.code == code)
  if (target && (val || val === 0 || val === '0') && val != undefined) {
    // if (Array.isArray(val)) {
    // 如果是数组
    let res = ''
    val
      .toString()
      .split(',')
      .forEach((item, index) => {
        // eslint-disable-next-line eqeqeq
        const a = target.children.find(item1 => item1.code == item)
        if (a) {
          res += `${index === 0 ? '' : ','}${a.name}`
        } else {
          res += ''
        }
        // eslint-disable-next-line eqeqeq
      })
    return res
  }
  return '--'
}
const formatTagType = (name, val) => {
  if (name === 'auditStatus') {
    return auditStatusTag[val]
  }
  return 'default'
}
/**
 * @description:
 * @param {type}
 * @return {type}
 */
const formart = (item, row, prop) => {
  return item.method(row, prop)
}
// 格式化字体颜色
const formatColorClass = (item, row, prop) => {
  return item.formatColorClass(row, prop)
}
/**
 * @description: 自动选中行样式更改
 * @param {type}
 * @return:
 */
const tableRowClassName = ({ row, rowIndex }) => {
  if (row) {
    row.index = rowIndex
    if (props.getIndex !== -1 && row.index === props.getIndex - 1) {
      return 'current-row'
    }
  }
}

const emit = defineEmits([
  'row',
  'select',
  'selectAll',
  'selectItem',
  'sortChangeTable'
])
/**
 * @description: 当行被点击
 * @param {type}
 * @return:
 */
const rowClick = val => {
  emit('row', val)
}

/**
 * @description: 多选
 * @param {type}
 * @return:
 */
const selectionChange = val => {
  emit('select', val)
}

const select = (arr, item) => {
  emit('selectItem', arr, item)
}

const selectAll = val => {
  emit('selectAll', val)
}

// 排序
const sortChange = val => {
  emit('sortChangeTable', val)
}

let cellList = []
let count = 0

const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
  if (props.isSummaryLastIndex) {
    if (rowIndex === props.data.length - 1) {
      // 处理合计，[1,2]表示合并1行2列，[0,0]表示改行不显示
      if (columnIndex === 1) {
        // 定位到最后一行，告诉该单元格合并1行2列
        return [1, 4]
      } else if (columnIndex === 1) {
        // 定位到6行1列的姓名，告诉该单元格不显示
        return [0, 0]
      }
    }
  }

  if (props.isMergeSameOrgRow) {
    computeCell(props.data)
    if (columnIndex === 0) {
      const fRow = cellList[rowIndex]
      const fCol = fRow > 0 ? 1 : 0
      return {
        rowspan: fRow, // 合并的行数
        colspan: fCol // 合并的列数，为0表示不显示
      }
    } else if (props.isMergeSameOrgCol2 && columnIndex === 1) {
      // 合并第二列
      const fRow = cellList[rowIndex]
      const fCol = fRow > 0 ? 1 : 0
      return {
        rowspan: fRow, // 合并的行数
        colspan: fCol // 合并的列数，为0表示不显示
      }
    }
  }
}

const computeCell = tableList => {
  cellList = []
  count = 0
  for (let i = 0; i < tableList.length; i++) {
    if (i === 0) {
      // 先设置第一项
      cellList.push(1) // 初为1，若下一项和此项相同，就往cellList数组中追加0
      count = 0 // 初始计数为0
    } else {
      if (tableList[i].orgCode == tableList[i - 1].orgCode) {
        cellList[count] += 1 // 增加计数
        cellList.push(0) // 相等就往cellList数组中追加0
      } else {
        cellList.push(1) // 不等就往cellList数组中追加1
        count = i // 将索引赋值为计数
      }
    }
  }
}

/**
 * 格式化标底的summary
 */
const summaryMethods = params => {
  const { columns, data } = params
  const sums = []
  columns.forEach((column, index) => {
    if (props.summary_type == 'SKMXD') {
      if (index === 0) {
        sums[index] = '金额合计'
        return
      }
      // else if (index === 1) {
      //   sums[index] = data !== null ? data.length + '所' : '-'
      //   return
      // }
      if (data && data.length !== 0) {
        console.log(column)
        const values = data.map(item => Number(item[column.property]))
        console.log(values)
        if (!values.every(value => isNaN(value))) {
          if (index == 1) {
            sums[index] = values.reduce((prev, curr) => {
              const value = Number(curr)
              if (!isNaN(value)) {
                return prev + curr
              } else {
                return prev
              }
            }, 0)
            sums[index] += ' 元'
          }
        } else {
          sums[index] = ''
        }
      }
    }
    if (props.summary_type == 'BTZJHB') {
      if (index === 0) {
        // sums[index] = '总计:'
        sums[index] = data !== null ? '总计：' + data.length + '家' : '-'
        return
      }
      if (
        index === 1 ||
        index === 4 ||
        index === 11 ||
        index === 9 ||
        index === 10
      ) {
        sums[index] = '-'
        return
      }
      if (data && data.length !== 0) {
        console.log(column)
        const values = data.map(item => Number(item[column.property]))
        console.log(values)
        if (!values.every(value => isNaN(value))) {
          sums[index] = values.reduce((prev, curr) => {
            const value = Number(curr)
            if (!isNaN(value)) {
              return prev + curr
            } else {
              return prev
            }
          }, 0)
          sums[index]
        } else {
          sums[index] = 'N/A'
        }
      }
    }
  })
  return sums
}

const windowWidth = ref(document.documentElement.clientWidth)

// 获取屏幕尺寸
const getWindowResize = function () {
  windowWidth.value = window.innerWidth
}

onBeforeMount(() => {
  getWindowResize()
  window.addEventListener('resize', getWindowResize)
})
onMounted(() => {
})
</script>
<style lang="scss" scoped>
.table-web {
  width: 100%;
  position: relative;
  overflow: hidden;
  /* height: calc(100% - 50px) */
}
.el-table {
  position: absolute;
}
.empty {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: #333;
  font-size: 14px;
  padding: 30px 0;
}
.emptyText {
  margin-left: 10px;
}
.error {
  color: red;
}
.table-web {
  font-family: 'Microsoft YaHei';
  :deep(.el-button) {
    border: 0 solid transparent !important;
    background-color: transparent !important;
    font-size: 14px !important;
    padding: 6px 0px !important;
    font-family: 'Microsoft YaHei';
  }
  :deep(.el-button + .el-button) {
    margin-left: 19px !important;
  }
  :deep(.el-button--success) {

    color: #087cd6 !important;
    &:hover {
      color: #087cd6 !important;
    }
  }
  :deep(.el-button--primary) {
    color: #087cd6 !important;
    &:hover {
      color: #087cd6 !important;
    }
  }
  :deep(.el-button--danger) {
    color: #087cd6 !important;
    &:hover {
      color: #087cd6 !important;
    }
  }
}
:deep(.el-popper) {
  max-width: 400px !important;
}

// 组件table表头高度和表格内容高度保持一致
:deep(.el-table__header) {
  .cell {
    // height: 30px!important;
    // line-height: 30px!important;
    padding: 3.5px 12px !important;
  }
}

:deep(.el-table) {
  color: #262626 !important;
}

:deep(.requiredName) > div.cell::before {
  content: '*';
  color: #f56c6c;
  margin-right: 4px;
}
</style>
